package com.freeLearning.boot.course.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.freeLearning.boot.common.annotation.Log;
import com.freeLearning.boot.common.enums.LogModuleEnum;
import com.freeLearning.boot.common.result.Result;
import com.freeLearning.boot.core.security.util.SecurityUtils;
import com.freeLearning.boot.course.enums.StatusEnum;
import com.freeLearning.boot.course.mapper.CourseInfoMapper;
import com.freeLearning.boot.course.model.VO.CourseInfoPageVO;
import com.freeLearning.boot.course.model.VO.CourseReviewPageVO;
import com.freeLearning.boot.course.model.entity.*;
import com.freeLearning.boot.course.model.query.CourseInfoPageQuery;
import com.freeLearning.boot.course.service.*;
import com.freeLearning.boot.shared.mail.service.MailService;
import com.freeLearning.boot.system.enums.MessageEnum;
import com.freeLearning.boot.system.model.entity.CourseCategory;
import com.freeLearning.boot.system.model.entity.Message;
import com.freeLearning.boot.system.model.entity.UserRole;
import com.freeLearning.boot.system.service.CourseCategoryService;
import com.freeLearning.boot.system.service.MessageService;
import com.freeLearning.boot.system.service.UserRoleService;
import com.freeLearning.boot.system.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Tag(name = "18.课程信息接口")
@RequestMapping("/api/v1/course")
@RestController
@RequiredArgsConstructor
public class CourseInfoController {
    private final long MAX_RECOMMEND_NUM = 12;
    private final CourseInfoService courseInfoService;
    private final CourseCategoryService courseCategoryService;
    private final CourseAuditService courseAuditService;
    private final CourseAuditHistoryService courseAuditHistoryService;
    private final CourseInfoMapper courseInfoMapper;
    private final MessageService messageService;
    private final MailService mailService;
    private final UserService userService;
    private final UserRoleService userRoleService;
    private final CourseReviewService courseReviewService;

    @PostMapping("/page")
    @Operation(summary = "分页查询课程")
    @Log(value = "分页查询课程", module = LogModuleEnum.COURSEINFO)
    public Result<IPage<CourseInfoPageVO>> page(@RequestBody CourseInfoPageQuery courseInfoPageQuery){
        IPage<CourseInfoPageVO> result =  courseInfoService.pageQuery(courseInfoPageQuery);
        return Result.success(result);
    }

    @PostMapping("/add")
    @Operation(summary = "新增课程")
    @Log(value = "新增课程", module = LogModuleEnum.COURSEINFO)
    public Result<Boolean> add(@RequestBody CourseInfo courseInfo){
        boolean result = courseInfoService.saveCourseInfo(courseInfo);
        List<UserRole> adminList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, 2));
        adminList.forEach(item->{
            Message message = Message.builder()
                    .title("有课程需要您审核")
                    .content("咨询师："+ courseInfo.getConsultantName() + "新增了课程《"+courseInfo.getTitle()+"》，请及时审核")
                    .type(MessageEnum.COURSE_AUDIT.getValue())
                    .publisherId(courseInfo.getConsultantId())
                    .publishTime(LocalDateTime.now())
                    .createBy(courseInfo.getConsultantId())
                    .acceptId(item.getUserId())
                    .build();
            messageService.sendMessage(message);
        });
        return Result.success(result);
    }
    @PostMapping("/update")
    @Operation(summary = "修改课程")
    @Log(value = "修改课程", module = LogModuleEnum.COURSEINFO)
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> update(@RequestBody CourseInfo courseInfo){
        courseInfo.setIsRecommend(com.freeLearning.boot.common.enums.StatusEnum.DISABLE.getValue());
        boolean result = courseInfoService.updateById(courseInfo);
        if (result){
            CourseAudit courseAudit = new CourseAudit();
            courseAudit.setStatus(StatusEnum.WAIT_AUDIT.getValue());
            courseAudit.setCourseId(courseInfo.getId());
            courseAudit.setAuditorId(SecurityUtils.getUserId());
            courseAudit.setAuditorName(courseInfo.getConsultantName());
            courseAudit.setOpinion("课程信息发生修改");
            courseAuditService.update(new UpdateWrapper<CourseAudit>()
                    .eq("course_id", courseInfo.getId())
                    .set("status", courseAudit.getStatus())
                    .set("audit_time", LocalDateTime.now()));
            courseAuditHistoryService.save(BeanUtil.copyProperties(courseAudit, CourseAuditHistory.class));
        }
        List<UserRole> adminList = userRoleService.list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, 2));
        adminList.forEach(item->{
            Message message = Message.builder()
                    .title("有课程需要您审核")
                    .content("课程《"+courseInfo.getTitle()+"》信息发生修改，请及时审核")
                    .type(MessageEnum.COURSE_AUDIT.getValue())
                    .publisherId(courseInfo.getConsultantId())
                    .publishTime(LocalDateTime.now())
                    .createBy(courseInfo.getConsultantId())
                    .acceptId(item.getUserId())
                    .build();
            messageService.sendMessage(message);
        });

        return Result.success(result);
    }

    @PostMapping("/update/status/{id}")
    @Operation(summary = "发布｜下架课程")
    @Log(value = "修改课程状态", module = LogModuleEnum.COURSEINFO)
    public Result<Boolean> updateStatus(@PathVariable Long id){
        CourseInfo courseInfo = courseInfoService.getById(id);
        if (!courseInfo.getStatus().equals(StatusEnum.PUBLISH.getValue()) &&
                !courseInfo.getStatus().equals(StatusEnum.WAIT_PUBLISH.getValue())){
            return Result.failed("课程审核通过后才能发布!");
        }
        if (courseInfo.getStatus().equals(StatusEnum.PUBLISH.getValue())){
            courseInfo.setStatus(StatusEnum.WAIT_PUBLISH.getValue());
        }else if (courseInfo.getStatus().equals(StatusEnum.WAIT_PUBLISH.getValue())){
            courseInfo.setStatus(StatusEnum.PUBLISH.getValue());
        }
        boolean b = courseInfoService.updateById(courseInfo);
        return Result.success(b);
    }

    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除课程")
    @Log(value = "删除课程", module = LogModuleEnum.COURSEINFO)
    public Result<Boolean> delete(@PathVariable Long id){
        boolean result = courseInfoService.removeById(id);
        return Result.success(result);
    }

    @PostMapping("/recommend/{id}")
    @Operation(summary = "推荐课程")
    @Log(value = "推荐课程", module = LogModuleEnum.COURSEINFO)
    @CacheEvict(value = "recommendCourse", allEntries = true)
    public Result<Boolean> recommend(@PathVariable Integer id){
        CourseInfo courseInfo = courseInfoService.getById(id);
        if (!courseInfo.getStatus().equals(StatusEnum.PUBLISH.getValue())){
            return Result.failed("课程未发布，不能推荐");
        }
        if (courseInfo.getIsRecommend() == null || courseInfo.getIsRecommend().equals(com.freeLearning.boot.common.enums.StatusEnum.DISABLE.getValue())){
            long isRecommendSize = courseInfoService.count(new QueryWrapper<CourseInfo>()
                    .eq("is_recommend", com.freeLearning.boot.common.enums.StatusEnum.ENABLE
                            .getValue()));
            if (isRecommendSize == MAX_RECOMMEND_NUM){
                return Result.failed("推荐课程已达上限");
            }
            courseInfo.setIsRecommend(com.freeLearning.boot.common.enums.StatusEnum.ENABLE.getValue());
        }else if (courseInfo.getIsRecommend().equals(com.freeLearning.boot.common.enums.StatusEnum.ENABLE.getValue())){
            courseInfo.setIsRecommend(com.freeLearning.boot.common.enums.StatusEnum.DISABLE.getValue());
        }
        boolean result = courseInfoService.updateById(courseInfo);
        Long userId = SecurityUtils.getUserId();
        Message message = Message.builder()
                .title("课程被推荐")
                .content("🎉您的课程《" + courseInfo.getTitle()+"》被推荐在平台主页啦！快去平台查看吧🎉！")
                .type(MessageEnum.RECOMMEND.getValue())
                .publisherId(userId)
                .publishTime(LocalDateTime.now())
                .createBy(userId)
                .acceptId(courseInfo.getConsultantId())
                .build();
        messageService.sendMessage(message);
        String email = userService.getById(courseInfo.getConsultantId()).getEmail();
        mailService.sendHTMLMail(email,
                "您的课程被推荐🎉",
                getCourseRecommendedMailContent(courseInfo.getTitle()),
                false
        );
        return Result.success(result);
    }

    @GetMapping("/recommend/list")
    @Operation(summary = "查询所有推荐的课程")
    @Log(value = "查询所有推荐的课程", module = LogModuleEnum.COURSEINFO)
    public Result<List<CourseInfoPageVO>> recommendList(){
        Map<String, Object> params = new HashMap<>();
        params.put("isRecommend", 1);
        List<CourseInfoPageVO> list = courseInfoMapper.getCourseList(params);
        return Result.success(list);
    }

    @Operation(summary = "查询所有已发布课程")
    @PostMapping("/allPublish/list")
    @Log(value = "查询所有已发布课程", module = LogModuleEnum.COURSEINFO)
    public Result<List<CourseInfoPageVO>> list(@RequestBody CourseInfo courseInfo){
        if (courseInfo.getCategoryId() != null){
            List<CourseCategory> categoryList = courseCategoryService.list(new QueryWrapper<CourseCategory>().eq("parent_id", courseInfo.getCategoryId()));
            List<CourseInfoPageVO> courseInfoList;
            if (categoryList.isEmpty()){
                Map<String, Object> params = new HashMap<>();
                params.put("categoryId", courseInfo.getCategoryId());
                courseInfoList = courseInfoMapper.getCourseList(params);
            }else{
                Map<String, Object> params = new HashMap<>();
                List<Long> categoryIds = categoryList.stream().map(CourseCategory::getId).collect(Collectors.toList());
                params.put("categoryIds", categoryIds);
                courseInfoList = courseInfoMapper.getCourseList(params);
            }
            return Result.success(courseInfoList);
        }else{
            List<CourseInfoPageVO> courseInfoList = courseInfoMapper.getCourseList(new HashMap<String,Object>());
            return Result.success(courseInfoList);
        }
    }

    @Operation(summary = "根据id查询课程详情")
    @GetMapping("/info/{id}")
    public Result<CourseInfoPageVO> getById(@PathVariable Long id){
        CourseInfoPageVO vo = courseInfoMapper.queryDetail(id);
        return Result.success(vo);
    }

    @Operation(summary = "根据咨询师 id 查询所有已发布课程")
    @PostMapping("/allPublish/listByConsultantId")
    @Log(value = " 根据咨询师 id 查询所有已发布课程", module = LogModuleEnum.COURSEINFO)
    public Result<List<CourseInfo>> listByConsultantId(@RequestBody CourseInfo courseInfo){
        List<CourseInfo> courseInfoList = courseInfoService.list(new QueryWrapper<CourseInfo>()
                .eq("status", StatusEnum.PUBLISH.getValue())
                .eq(courseInfo.getConsultantId() != null,"consultant_id", courseInfo.getConsultantId())
                .orderByDesc("create_time"));
        return Result.success(courseInfoList);
    }
    private String getCourseRecommendedMailContent(String courseName) {
        StringBuilder content = new StringBuilder();
        content.append("<html><body style='font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px;'>");
        content.append("<div style='background-color: #ffffff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);'>");

        // 添加平台Logo和标题
        content.append("<img src='http://www.free-learning.icu/images/logo.png' alt='公益性教育咨询平台' style='width: 150px; height: auto; display: block; margin: 0 auto;'><br>");
        content.append("<h1 style='color: #333333; text-align: center;'>课程推荐通知</h1>");

        // 用户问候
        content.append("<p style='color: #666666;'>尊敬的用户：</p>");
        content.append("<p style='color: #666666;'>\uD83C\uDF89恭喜您！您的课程 <strong style='color: #28a745;'>").append(courseName).append("</strong> 已被推荐到系统首页！</p>");

        // 推荐说明
        content.append("<p style='color: #666666;'>您的课程因其高质量的内容和受欢迎程度被选中推荐。这是一个让更多人了解您的课程的绝佳机会！</p>");

        // 操作建议
        content.append("<p style='color: #666666;'>您可以前往 <a href='http://www.free-learning.icu/' style='color: #007bff;'>公益性教育咨询平台</a> 查看，感谢您对公益性教育咨询平台的贡献。</p>");

        // 结尾
        content.append("<p style='color: #666666;'>感谢您对 <a href='http://www.free-learning.icu/' style='color: #007bff;'>公益性教育咨询平台</a> 的支持！</p>");
        content.append("<p style='color: #666666;'>祝您生活愉快！</p>");
        content.append("</div>");
        content.append("</body></html>");
        return content.toString();
    }

    @Operation(summary = "根据课程 id查询课程所有评论")
    @GetMapping("/queryComment")
    public Result<IPage<CourseReviewPageVO>> queryComment(
            @RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam Long courseId,
            @RequestParam String sortKey
    ){
        Long userId = SecurityUtils.getUserId();
        IPage<CourseReviewPageVO> page = courseReviewService.queryPageByCourseId(pageNum,pageSize,courseId,userId,sortKey);
        return Result.success(page);
    }

    @Operation(summary = "根据课程 id查询课程所有已发布评论")
    @GetMapping("/queryPublishComment")
    public Result<IPage<CourseReviewPageVO>> queryPublishComment(
            @RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam Long courseId,
            @RequestParam String sortKey
    ){
        Long userId = SecurityUtils.getUserId();
        IPage<CourseReviewPageVO> page = courseReviewService.queryPageByCourseIdNoUserId(pageNum,pageSize,courseId,userId,sortKey);
        return Result.success(page);
    }
}


